/*
 * Copyright 2011 www.pretty-tools.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include "stdafx.h"
#include "PrefBranch.h"


// CPrefBranch

CPrefBranch::CPrefBranch()
{
    ATLTRACE( _T("CPrefBranch::CPrefBranch()\n") );
}

CPrefBranch::~CPrefBranch()
{
    ATLTRACE( _T("CPrefBranch::~CPrefBranch()\n") );
}

STDMETHODIMP CPrefBranch::Init(BSTR aPrefRoot)
{
    if (!aPrefRoot)
        return E_INVALIDARG;

    ATLTRACE( L"CPrefBranch::Init(\"%s\")\n", aPrefRoot );

    CStringW strPrefRoot = aPrefRoot;
    strPrefRoot.Replace( L'.', L'\\' );
    
    return InitWithKey(CComBSTR((CStringW)L"XPCOMAdapter\\" + strPrefRoot));
}

STDMETHODIMP CPrefBranch::InitWithKey(BSTR aPrefRoot)
{
    if (!aPrefRoot)
        return E_INVALIDARG;
    if (m_key)
        return E_UNEXPECTED;

    ATLTRACE( L"CPrefBranch::InitWithKey(\"%s\")\n", aPrefRoot );

	CString strRootKey;

	if (IsOSVistaOrHigher())
		strRootKey = _T("Software\\Microsoft\\Internet Explorer\\LowRegistry\\");
	else
		strRootKey = _T("Software\\");

    RETURN_HRESULT(m_key.CreateEx(HKEY_CURRENT_USER, strRootKey + (CString)aPrefRoot));
}

STDMETHODIMP CPrefBranch::prefHasUserValue(BSTR aPrefName, VARIANT_BOOL* pRet)
{
    if (!aPrefName)
        return E_INVALIDARG;
    if (!pRet)
        return E_POINTER;
    if (!m_key)
        return E_UNEXPECTED;

    ATLTRACE( L"CPrefBranch::prefHasUserValue(\"%s\")\n", aPrefName );

    *pRet = ToVariant(m_key.IsValueSet(aPrefName));

    return S_OK;
}

STDMETHODIMP CPrefBranch::getBoolPref(BSTR aPrefName, VARIANT_BOOL* pRet)
{
    if (!aPrefName)
        return E_INVALIDARG;
    if (!pRet)
        return E_POINTER;
    if (!m_key)
        return E_UNEXPECTED;

    ATLTRACE( L"CPrefBranch::getBoolPref(\"%s\")\n", aPrefName );

    bool bValue = false;
    RETURN_E_FAIL_ON_FALSE(m_key.QueryValue(aPrefName, bValue))

    *pRet = ToVariant(bValue);

    return S_OK;
}

STDMETHODIMP CPrefBranch::setBoolPref(BSTR aPrefName, VARIANT_BOOL aValue)
{
    if (!aPrefName)
        return E_INVALIDARG;
    if (!m_key)
        return E_UNEXPECTED;

    ATLTRACE( L"CPrefBranch::setBoolPref(\"%s\")\n", aPrefName );

    RETURN_HRESULT(ERROR_SUCCESS == m_key.SetValue(aPrefName, (VARIANT_TRUE == aValue)));
}

STDMETHODIMP CPrefBranch::getCharPref(BSTR aPrefName, BSTR* pRet)
{
    if (!aPrefName)
        return E_INVALIDARG;
    if (!pRet)
        return E_POINTER;
    if (!m_key)
        return E_UNEXPECTED;

    ATLTRACE( L"CPrefBranch::getCharPref(\"%s\")\n", aPrefName );

    CComBSTR bsValue;
    RETURN_E_FAIL_ON_FALSE(m_key.QueryValue(aPrefName, bsValue))

    *pRet = bsValue.Detach();

    return S_OK;
}

STDMETHODIMP CPrefBranch::setCharPref(BSTR aPrefName, BSTR aValue)
{
    if (!aPrefName)
        return E_INVALIDARG;
    if (!m_key)
        return E_UNEXPECTED;

    ATLTRACE( L"CPrefBranch::setCharPref(\"%s\")\n", aPrefName );

    RETURN_HRESULT(ERROR_SUCCESS == m_key.SetValue(aPrefName, aValue));
}

STDMETHODIMP CPrefBranch::getIntPref(BSTR aPrefName, LONG* pRet)
{
    if (!aPrefName)
        return E_INVALIDARG;
    if (!pRet)
        return E_POINTER;
    if (!m_key)
        return E_UNEXPECTED;

    ATLTRACE( L"CPrefBranch::getIntPref(\"%s\")\n", aPrefName );

    DWORD dwValue = 0;
    RETURN_E_FAIL_ON_FALSE(m_key.QueryValue(aPrefName, dwValue))

    *pRet = (LONG)dwValue;

    return S_OK;
}

STDMETHODIMP CPrefBranch::setIntPref(BSTR aPrefName, LONG aValue)
{
    if (!aPrefName)
        return E_INVALIDARG;
    if (!m_key)
        return E_UNEXPECTED;

    ATLTRACE( L"CPrefBranch::setIntPref(\"%s\")\n", aPrefName );

    RETURN_HRESULT(ERROR_SUCCESS == m_key.SetValue(aPrefName, (DWORD)aValue));
}

STDMETHODIMP CPrefBranch::getInt64Pref(BSTR aPrefName, LONGLONG* pRet)
{
    if (!aPrefName)
        return E_INVALIDARG;
    if (!pRet)
        return E_POINTER;
    if (!m_key)
        return E_UNEXPECTED;

    ATLTRACE( L"CPrefBranch::getInt64Pref(\"%s\")\n", aPrefName );

    *pRet = 0;
    RETURN_E_FAIL_ON_FALSE(m_key.QueryValue(aPrefName, *pRet))

    return S_OK;
}

STDMETHODIMP CPrefBranch::setInt64Pref(BSTR aPrefName, LONGLONG aValue)
{
    if (!aPrefName)
        return E_INVALIDARG;
    if (!m_key)
        return E_UNEXPECTED;

    ATLTRACE( L"CPrefBranch::setInt64Pref(\"%s\")\n", aPrefName );

    RETURN_HRESULT(ERROR_SUCCESS == m_key.SetValue(aPrefName, aValue));
}
